﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Client.p2p
{
    /// <summary>
    /// Occurs when a command received.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">The information about the received command.</param>
    public delegate void CommandReceivedEventHandler(object sender, CommandEventArgs e);

    /// <summary>
    /// Occurs when a command had been sent Successfully.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void CommandSentEventHandler(object sender, CommandEventArgs e);

    /// <summary>
    /// Occurs when a command sending action had been failed.This is because disconnection or sending exception.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void CommandSendingFailedEventHandler(object sender, CommandEventArgs e);

    /// <summary>
    /// The class that contains information about a command.
    /// </summary>
    public class CommandEventArgs : EventArgs
    {
        private Command command;
        /// <summary>
        /// The received command.
        /// </summary>
        public Command Command
        {
            get { return command; }
        }

        /// <summary>
        /// Creates an instance of CommandEventArgs class.
        /// </summary>
        /// <param name="cmd">The received command.</param>
        public CommandEventArgs(Command cmd)
        {
            this.command = cmd;
        }
    }

    /// <summary>
    /// Occurs when the server had been disconnected from this client.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">The server information.</param>
    public delegate void RemoteDisconnectedEventHandler(object sender, RemoteEventArgs e);

    /// <summary>
    /// Occurs when this client disconnected from the server.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void DisconnectedFromRemoteEventHandler(object sender, RemoteEventArgs e);

    /// <summary>
    /// The class that contains information about the counterpart.
    /// </summary>
    public class RemoteEventArgs : EventArgs
    {
        private Socket socket;
        /// <summary>
        /// The IP address of server.
        /// </summary>
        public IPAddress IP
        {
            get { return ((IPEndPoint)this.socket.RemoteEndPoint).Address; }
        }
        /// <summary>
        /// The port of server.
        /// </summary>
        public int Port
        {
            get { return ((IPEndPoint)this.socket.RemoteEndPoint).Port; }
        }
        /// <summary>
        /// Creates an instance of ServerEventArgs class.
        /// </summary>
        /// <param name="clientSocket">The client socket of current CommandClient instance.</param>
        public RemoteEventArgs(Socket socket)
        {
            this.socket = socket;
        }
    }

    /// <summary>
    /// Occurs when this client connected to the remote server Successfully.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void ConnectingSuccessedEventHandler(object sender, ConnectEventArgs e);

    /// <summary>
    /// Occurs when this client failed on connecting to server.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void ConnectingFailedEventHandler(object sender, ConnectEventArgs e);

    /// <summary>
    /// ConnectEventArgs
    /// </summary>
    public class ConnectEventArgs : EventArgs
    {
        private IPEndPoint endpoint;

        public IPAddress IP
        {
            get { return endpoint.Address; }
        }

        public int Port
        {
            get { return endpoint.Port; }
        }

        public ConnectEventArgs(IPEndPoint endpoint)
        {
            this.endpoint = endpoint;
        }
    }

    public delegate void MessageReceivedEventHandler(object sender, MessageEventArgs e);

    public delegate void MessageSentEventHandler(object sender, MessageEventArgs e);

    public delegate void MessageSendingFailedEventHandler(object sender, MessageEventArgs e);

    public class MessageEventArgs : EventArgs
    {
        private Message msg;
        public Message Msg
        {
            get { return msg; }
        }

        public MessageEventArgs(Message msg)
        {
            this.msg = msg;
        }
    }

    public delegate void UserOnlineEventHandler(object sender, UserEventArgs e);

    public delegate void UserOfflineEventHandler(object sender, UserEventArgs e);

    public class UserEventArgs : EventArgs
    {
        private string name;
        public string Username
        {
            get { return name; }
        }

        public UserEventArgs(string name)
        {
            this.name = name;
        }
    }

    public delegate void FileTransferProgressChangedEventHandler(object sender, FileTransferProgressChangedEventArgs e);

    public class FileTransferProgressChangedEventArgs: EventArgs
    {
        private FileAttr fileAttr;
        public FileAttr FileAttr
        {
            get { return fileAttr; }
        }

        public long ByteHasTransfered = 0;
        public int ByteTransferThisTime;

        public FileTransferProgressChangedEventArgs(FileAttr fileAttr)
        {
            this.fileAttr = fileAttr;
        }

        public FileTransferProgressChangedEventArgs Transfer(int bytes)
        {
            this.ByteTransferThisTime = bytes;
            this.ByteHasTransfered += bytes;
            return this;
        }
    }

    public delegate void FileReceivingEventHandler(object sender, FileReceivingEventArgs e);

    public class FileReceivingEventArgs : EventArgs
    {
        private FileAttr fileAttr;
        public FileAttr FileAttr
        {
            get { return fileAttr; }
        }

        public string TargetName;

        public FileReceivingEventArgs(string TargetName, FileAttr fileAttr)
        {
            this.TargetName = TargetName;
            this.fileAttr = fileAttr;
        }
    }

    public delegate void FileConfirmedEventHandler(object sender, FileConfirmedEventArgs e);

    public class FileConfirmedEventArgs : EventArgs
    {
        public int FileAttrNo;
        public string TargetName;
        public IPEndPoint EndPoint;

        public FileConfirmedEventArgs(string TargetName, IPEndPoint endpoint, int FileAttrNo)
        {
            this.TargetName = TargetName;
            this.EndPoint = endpoint;
            this.FileAttrNo = FileAttrNo;
        }
    }

    public delegate void FileDeniedEventHandler(object sender, FileTransferEventArgs e);

    public class FileTransferEventArgs : EventArgs
    {
        public int FileAttrNo;
        public string TargetName;

        public FileTransferEventArgs(string TargetName, int FileAttrNo)
        {
            this.TargetName = TargetName;
            this.FileAttrNo = FileAttrNo;
        }
    }

    public delegate void FileCanceledEventHandler(object sender, FileCanceledEventArgs e);

    public class FileCanceledEventArgs : EventArgs
    {
        public int FileAttrNo;
        public string FileAttrSource;
        public string TargetName;

        public FileCanceledEventArgs(string TargetName, int FileAttrNo, string FileAttrSource)
        {
            this.TargetName = TargetName;
            this.FileAttrNo = FileAttrNo;
            this.FileAttrSource = FileAttrSource;
        }
    }

    public delegate void FileTransferFinishedEventHandler(object sender, FileTransferFinishedEventArgs e);

    public class FileTransferFinishedEventArgs : EventArgs
    {
        public bool Canceled;
        public bool Crashed;
        public bool Succeeded;

        public FileTransferFinishedEventArgs(bool Succeeded, bool Canceled, bool Crashed)
        {
            this.Succeeded = Succeeded;
            this.Canceled = Canceled;
            this.Crashed = Crashed;
        }
    }

    /// <summary>
    /// Occurs when the network had been failed.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void NetworkDeadEventHandler(object sender, EventArgs e);

    /// <summary>
    /// Occurs when the network had been started to work.
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">EventArgs.</param>
    public delegate void NetworkAlivedEventHandler(object sender, EventArgs e);

}